<template>
	<div class="v-view">
		<Breadcrumb moduleName="自定义查询"></Breadcrumb>
		<div class="box-selfquery">
			<div class="screen">
				<div class="analysis">
					<div>
						<a-menu
							style="width: 100%"
							:default-selected-keys="['1']"
							:open-keys.sync="openKeys"
							mode="inline"
							@click="handleClick"
						>
							<a-sub-menu @titleClick="titleClick" key="sub1">
								<span slot="title" style="color: rgba(32,50,89,0.45);font-family: PingFangSC-Regular;font-size: 12px;">原始日志数据</span>
								<a-sub-menu v-for="(item, key) in sqlList" :key="key" :title="item.tableName" >
									<a-menu-item v-for="(obj, index) in item.columns" :key="index" :title="obj.attrCode">
										{{ obj.attrCode }}
									</a-menu-item>
								</a-sub-menu>
							</a-sub-menu>
						</a-menu>
					</div>
				</div>
			</div>
			<div class="data-view">
				<div class="right">
					<a-space>
						<a-button type="primary" @click="saveSqlList">保存</a-button>
						<a-button @click="querySqlList">查询列表</a-button>
					</a-space>
				</div>
				<div class="data_SQL">
					<h4 style="color: #203259;font-size: 16px;font-family: PingFangSC-Semibold;">执行SQL语句</h4>
				</div>
				<div class="data_input">
					<!-- <textarea v-model="saveSql.sqlText" /> -->
					<codemirror v-model="saveSql.sqlText" :options="cmOption" />
				</div>
				<div class="data_prompt">
					<span>
						<h4 style="color: rgba(32,50,89,0.65);font-family: PingFangSC-Regular;font-size: 14px;">页面只显示前 1000 条结果；下载默认最大 1000 条</h4>
					</span>
				</div>
				<div class="execute_emptying">
					<a-space>
						<a-button type="primary" @click="implementSql">执行</a-button>
						<a-button @click="emptySql">清空</a-button>
					</a-space>
				</div>
				<div class="result_view">
					<div class="result_log">
						<a-tabs default-active-key="1" @change="callback">
							<a-tab-pane key="1" tab="结果">
								<Result v-if="resIf" :resultData="resultData"></Result>
								<div v-else style="height: 168px"></div>
							</a-tab-pane>
							<a-tab-pane key="2" tab="日志" force-render>
								<Log v-if="logIf" :logData="logData"></Log>
							</a-tab-pane>
							<div slot="tabBarExtraContent" class="iconSlot">
								<a-space>
									<a-button icon="download" @click="downloadClick" />
									<a-popover placement="topRight" title="说明">
										<template slot="content">
											<div style="padding: 2px 20px 16px 2px">
												<span style="font-size: 15px; font-weight: bold">查询:</span>
												<span style="margin-left: 10px">查询最多返回1w条数据，超过1w条数据不返回。</span>
											</div>
											<div>
												<span style="font-size: 16px; font-weight: bold">下载:</span>
												<span style="margin-left: 10px">
														只支持当前查询的1w条数据，超过部分，可联系管理员，进行数据抽取。
												</span>
											</div>
										</template>
										<a-icon type="question-circle"/>
									</a-popover>
								</a-space>
							</div>
						</a-tabs>
					</div>
				</div>
			</div>
		</div>
		<div class="view_dialog">
			<a-modal v-model="dialogModal" title="保存查询" @ok="handleOk" @cancel="cancel">
				<a-form-model ref="saveSqlrules" :model="saveSql" :rules="saveSqlrules"  :label-col="{ span: 5 }" :wrapper-col="{ span: 18 }">
					<a-form-model-item has-feedback label="查询名称" prop="sqlName">
						<a-input v-model="saveSql.sqlName" type="text"
										 placeholder="请输入中文、字母、数字的组合"/>
					</a-form-model-item>
					<a-form-model-item has-feedback label="描述" prop="sqlDesc">
						<a-input v-model="saveSql.sqlDesc" type="textarea"
										 placeholder="请输入最少五个字符"/>
					</a-form-model-item>
				</a-form-model>
			</a-modal>
		</div>
	</div>
</template>

<script lang="ts">
	import { Component, Prop, Vue } from 'vue-property-decorator'
	import Breadcrumb from '@/layout/components/Breadcrumb/index.vue'
	import Shortcuts from '@/layout/components/Breadcrumb/Shortcuts.vue'
	import Result from '../assembly/result.vue'
	import Log from '../assembly/log.vue'
	import { codemirror } from 'vue-codemirror'
	import 'codemirror/lib/codemirror.css'
	import 'codemirror/theme/solarized.css'
	import 'codemirror/mode/sql/sql.js'
	import {
		saveSqlSentence,
		querySqlSentence,
		querySqltables,
		sqlDownload
	} from '@/api/sql'

	@Component({
		components: {
			Breadcrumb,
			Shortcuts,
			Result,
			Log,
			codemirror
		}
	})

	export default class SelfQuery extends Vue {
		@Prop() private msg!: string
		private sqlNameMyRule = (rule:any, value:any, callback:any) => {
			let reg = new RegExp(/^[\u4e00-\u9fa5a-zA-Z0-9]{4,50}$/)
			let result = reg.test(value)
			if (!result) {
				callback('请您输入4-50个中英文字符的查询名称(不能输入特殊字符)')
			} else {
				callback()
			}
		};
		private sqlDescMyRule = (rule:any, value:any, callback:any) => {
			let reg = new RegExp(/^[\u4e00-\u9fa5a-zA-Z0-9]{4,100}$/)
			let result = reg.test(value)
			if (!result) {
				callback('请您输入4-100个中英文字符的描述(不能输入特殊字符)')
			} else {
				callback()
			}
		};
		private resIf = false
		private logIf = false
		private resultData = []
		private logData: Array<any> = []
		private openKeys = ['sub1']
		private sqlList = []
		private dialogModal = false
		private	 saveSqlrules = {
			sqlName: [
				{ required: true, message: '查询名称必须填写', trigger: 'blur' },
				{ validator: this.sqlNameMyRule, trigger: 'change' }],
			sqlDesc: [
				{ required: true, message: '描述必须填写', trigger: 'blur' },
				{ validator: this.sqlDescMyRule, trigger: 'change' }
			],
		}
		private saveSql = {
			createTime: '',
			createUser: '',
			id: 0,
			projectId: localStorage.getItem('productId'),
			sqlDesc: '',
			sqlName: '',
			sqlText: '',
			updateTime: '',
			updateUser: ''
		}
		cmOption = {
			tabSize: 4,
			styleActiveLine: true,
			lineNumbers: true,
			line: true,
			mode: 'text/x-mysql',
			theme: 'solarized light'
		}

		mounted(): void {
			let param: any = this.$route.query.editData
			if (param && param.sqlText != undefined) {
				this.saveSql.sqlText = param.sqlText
			} else {
				this.saveSql.sqlText = ''
			}
			this.querySqltables()
		}
		handleClick(e: any) {
			console.log('click', e)
		}
		titleClick(e: any) {
			console.log('titleClick', e)
		}

		callback(key: any) {
			if (key == 1) {
				this.resIf = true
				this.logIf = false
			} else if (key == 2) {
				this.logIf = true
				this.resIf = false
			}
		}

		querySqlList() {
			this.$router.push({ path: '/behavioural/selflist' })
		}

		saveSqlList() {
			if (this.saveSql.sqlText != '') {
				this.dialogModal = true
			} else {
				this.$message.warning('输入语句为空，请输入sql语句后，再点击保存。')
			}
		}

		handleOk() {
			const fomObj:any = this.$refs.saveSqlrules
			fomObj.validate((valid:any) => {
				if (valid) {
					this.saveSqlSentence()
					this.dialogModal = false
				} else {
					return false
				}
			})
		}

		cancel() {
			this.saveSql.sqlDesc = ''
			this.saveSql.sqlName = ''
		}

		emptySql() {
			this.saveSql.sqlText = ''
			this.resultData = []
			this.resIf = false
		}

		implementSql() {
			if (this.saveSql.sqlText != '') {
				let params = {
					projectId: localStorage.getItem('productId') || '',
					sql: this.saveSql.sqlText
				}
				this.querySqlSentence(params)
			} else {
				this.$message.warning('输入sql语句为空，请输入sql语句后，再点击执行。')
				this.resIf = false
				this.resultData = []
			}
		}

		downloadClick() {
			if (this.resultData.length > 0) {
				let params = {
					projectId: localStorage.getItem('productId') || '',
					sql: this.saveSql.sqlText
				}
				sqlDownload(params).then(res => {
					let response:any = res
					let link = document.createElement("a") //创建一个a标签
					link.href = window.URL.createObjectURL(new Blob([response])) //将请求到的流地址赋值给a标签
					link.target = "_blank"  //规定在何处打开链接文档。
					link.download = "sql文件.xlsx" //文件名和格式
					document.body.appendChild(link)
					link.click()
					document.body.removeChild(link)
				}).catch((err: any) => {
					this.$message.error(err.msg || err.message, 5)
				})
			} else {
				this.$message.warning('请输入sql语句，点击执行，查询到列表后才能下载列表。')
			}
		}

		//表列表接口
		querySqltables() {
			let params = {
				projectId: localStorage.getItem('productId') || '',
				sql: 'select count(1) from user'
			}
			querySqltables(params)
				.then(res => {
					if (res.code == 200) {
						this.sqlList = res.data
					} else {
						console.log('res=', res)
					}
				}).catch((err: any) => {
				this.$message.error(err.msg || err.message, 5)
			})
		}

		//保存查询sql接口
		saveSqlSentence() {
			saveSqlSentence(this.saveSql)
				.then(res => {
					if (res.code == 200) {
						this.$message.success('保存成功')
						this.saveSql.sqlDesc = ''
						this.saveSql.sqlName = ''
					} else {
						this.$message.warning('保存失败')
						console.log('saveSqlSentence请求失败')
					}
				}).catch((err: any) => {
				this.$message.error(err.msg || err.message, 5)
			})
		}

		//sql查询接口
		querySqlSentence(params: any) {
			this.resIf = false
			querySqlSentence(params)
				.then(res => {
					if (res.code == 200) {
						this.resultData = res.data.list
						this.resIf = true
						//存储执行sql语句，做日志显示使用
						//let time = new Date().toLocaleTimeString('chinese', { hour12: false })
						let message = res.data.message || ""
						let obj = { runMessage: message, sqlText: this.saveSql.sqlText, sqlTips: res.data.warn }
						this.logData.unshift(obj)
						if(!(res.data.status)){
							this.$message.warning(res.data.message)
						}
					} else {
						console.log('querySqlSentence请求失败')
					}
				}).catch((err: any) => {
				this.$message.error(err.msg || err.message, 5)
			})
		}

	}
</script>

<style lang="scss" scoped>
	.v-view {
		height: 100%;
	}
	.box-selfquery {
		display: flex;
		justify-content: space-between;
		width: 100%;
		height: calc(100% - 56px);
		.screen {
			position: relative;
			width: 248px;
			height: 100%;
			box-sizing: content-box;
			background: #fff;
			.analysis {
				height: calc(100% - 60px);
				overflow-y: scroll;
				padding: 10px 10px 10px 2px;
			}
			.box-btn {
				position: absolute;
				right: 0;
				bottom: 0;
				width: 100%;
				border-top: 1px solid #e9e9e9;
				padding: 10px 16px;
				background: #fff;
				text-align: right;
				z-index: 1;
				.btn {
					display: inline-block;
					margin-left: 8px;
				}
			}
		}
		.data-view {
			overflow-y: auto;
			flex: 1;
			height: calc(100% - 16px);
			margin: 16px;
			margin-bottom: 0;
			padding: 20px 24px;
			background: #fff;
			@include scrollBar;
		}
	}
	.right {
		float: right;
	}
	.data_input {
		margin-top: 25px;
		::v-deep .CodeMirror{
			height: 120px;
		}
		::v-deep .cm-s-solarized.cm-s-light{
			background: #fff;
			.CodeMirror-gutters{
				background-color:  #F3F8FE;
			}
		}
		::v-deep .cm-s-solarized.CodeMirror{
			border: 1px solid #D8DCE6;
			//    border-left: none;
			border-radius: 2px;
		}

		// background-color: #9aa2b4;
		// padding: 0 0 0 20px;
		// textarea {
		// 	margin-bottom: -2px;
		// 	width: 100%;
		// 	height: 70px;
		// }
	}
	.data_prompt {
		margin-top: 5px;
		span {
			h4 {
				margin-left: 20px;
			}
		}
	}
	.execute_emptying {
		margin-top: 15px;
	}

	.result_view {
		margin-top: 10px;
		border: 1px solid $border;
		width: 100%;
		overflow: auto;
	}
	.result_log {
		width: 100%;
		.iconSlot {
			float: right;
			margin-right: 20px;
		}
	}
	/deep/.cm-s-solarized.CodeMirror {
		 box-shadow: none;
	}
</style>
